package com.qys.livesMall.shop.controller.app;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.service.IH2AppUserService;
import com.qys.livesMall.cache.words.annotation.CheckWord;
import com.qys.livesMall.common.constants.Constants;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.common.utils.MessageUtils;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.shop.modal.dto.OrderCommentDto;
import com.qys.livesMall.shop.modal.entity.ShopGoodsInfo;
import com.qys.livesMall.shop.modal.entity.ShopGoodsSku;
import com.qys.livesMall.shop.modal.entity.ShopOrderComment;
import com.qys.livesMall.shop.modal.entity.ShopOrderSku;
import com.qys.livesMall.shop.modal.query.QueryOrderComment;
import com.qys.livesMall.shop.modal.vo.OrderCommentVo;
import com.qys.livesMall.shop.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 商品评论表 前端控制器
 * </p>
 *
 * @author gmx
 * @since 2023-06-30
 */
@RestController
@RequestMapping("/app/shopOrderComment")
@Tag(name = "app-商品评论",description = "app-商品评论")
public class AppShopOrderCommentController {
    @Resource
    private IH2AppUserService userService;
    @Resource
    private ShopOrderCommentService commentService;
    @Resource
    private ShopOrderSkuService skuService;
    @Resource
    private ShopGoodsSkuService goodsSkuService;
    @Resource
    private ShopGoodsInfoService goodsInfoService;
    @Resource
    private H2ShopBaseService shopBaseService;
    @Resource
    private ShopScoreService shopScoreService;

    @Operation(summary = "添加评论")
    @PostMapping("/add")
    @CheckWord
    @Transactional(rollbackFor = Exception.class)
    public R add(@RequestBody List<OrderCommentDto> commentDto){
        long now = new Date().getTime();
        H2AppUser appUser = userService.getById(SecurityUtils.getUserId());
        for (OrderCommentDto orderCommentDto : commentDto) {
            ShopOrderComment orderComment = new ShopOrderComment();
            BeanUtil.copyProperties(orderCommentDto,orderComment);
            //查询订单
            ShopOrderSku orderSku = skuService.getById(orderCommentDto.getOrderId());
            ShopGoodsSku goodSku = goodsSkuService.getById(orderSku.getSkuId());
            ShopGoodsInfo goodsInfo = goodsInfoService.getById(goodSku.getShopGoodsId());

            orderComment.setType("1");
            orderComment.setShopId(goodsInfo.getShopId().toString());
            orderComment.setGoodsId(goodsInfo.getId().toString());
            orderComment.setGoodsName(goodsInfo.getGoodsName());
            orderComment.setSkuName(goodSku.getSkuName());
            orderComment.setUserId(appUser.getId());
            orderComment.setDeleted(false);
            orderComment.setUserName(appUser.getNickName());
            orderComment.setUserAvatar(appUser.getAvatar());
            orderComment.setEnable("1");
            orderComment.setCreatedTime(now);
            orderComment.setUpdatedTime(now);
            orderComment.setProductScore(orderCommentDto.getShopScore().getProductScore());
            orderComment.setLogisticsScore(orderCommentDto.getShopScore().getLogisticsScore());
            orderComment.setAfterSaleScore(orderCommentDto.getShopScore().getAfterSaleScore());
            orderComment.setConsultScore(orderCommentDto.getShopScore().getConsultScore());
            if(!commentService.save(orderComment))R.fail(MessageUtils.message("system.error.comment"));

            //更新店铺评分
            shopScoreService.setMark(orderCommentDto.getShopScore());

            //更新订单评价状态
            orderSku.setReview(Constants.YesNo.YES);
            skuService.updateById(orderSku);
        }
        return R.ok();
    }

    @Operation(summary = "点赞评论")
    @PostMapping("/likeComment/{commentId}")
    public synchronized R<?> likeComment(@PathVariable Long commentId){

        boolean had = commentService.haveLiked(commentId, SecurityUtils.getUserId());
        if(had){
            return R.fail(MessageUtils.message("non.repeatable.operation"));
        }

        commentService.saveLike(commentId, SecurityUtils.getUserId());

        ShopOrderComment comment = commentService.getById(commentId);
        if(comment != null){
            comment.setLikeNum(comment.getLikeNum() + 1);
            commentService.updateById(comment);
        }
        return R.ok();
    }

    @Operation(summary = "评论列表")
    @PostMapping("/page")
    public R<Page<OrderCommentVo>> page(@RequestBody @Validated QueryOrderComment queryOrderComment){
        Page<ShopOrderComment> page = Page.of(queryOrderComment.getCurrent(), queryOrderComment.getSize());
        LambdaQueryWrapper<ShopOrderComment> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtils.isEmpty(queryOrderComment.getGoodsId()))return R.fail(MessageUtils.message("system.error"));
        queryWrapper.eq(ShopOrderComment::getGoodsId,queryOrderComment.getGoodsId());
        queryWrapper.eq(ShopOrderComment::getParentId,"0");
        if (ObjectUtils.isNotEmpty(queryOrderComment.getRating())){
            if (!queryOrderComment.getRating().equals("0")){
                queryWrapper.eq(ShopOrderComment::getRating,queryOrderComment.getRating());
            }
        }
        queryWrapper.eq(ShopOrderComment::getEnable,"1");
        queryWrapper.eq(ShopOrderComment::getDeleted,false);
        queryWrapper.orderByDesc(ShopOrderComment::getCreatedTime);
        Page<ShopOrderComment> commentList = commentService.page(page, queryWrapper);
        Page<OrderCommentVo> pageTree = new Page<>();
        BeanUtil.copyProperties(commentList,pageTree);
        pageTree.setRecords(new ArrayList<OrderCommentVo>());
        for (ShopOrderComment record : commentList.getRecords()) {
            OrderCommentVo commentVo = new OrderCommentVo();
            BeanUtil.copyProperties(record,commentVo);
            LambdaQueryWrapper<ShopOrderComment> queryWrapperChild = new LambdaQueryWrapper<>();
            queryWrapperChild.eq(ShopOrderComment::getParentId,record.getId());
            List<ShopOrderComment> commentChild = commentService.list(queryWrapperChild);
            commentVo.setChildOrderComent(commentChild);
            pageTree.getRecords().add(commentVo);
        }
        //计算商品平均分
        List<ShopOrderComment> fractionalList = commentService.list(Wrappers.<ShopOrderComment>lambdaQuery()
                .select(ShopOrderComment::getProductScore)
                .eq(ShopOrderComment::getGoodsId, queryOrderComment.getGoodsId())
                .isNotNull(ShopOrderComment::getProductScore));

        if(CollectionUtil.isNotEmpty(fractionalList)){
            BigDecimal totalScore = fractionalList.stream()
                    .map(ShopOrderComment::getProductScore)
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(new BigDecimal(fractionalList.size()), 2, RoundingMode.DOWN);;
            pageTree.setCountId(totalScore.toString());
        }
        return R.ok(pageTree);
    }
    @Operation(summary = "商家评论列表")
    @PostMapping("/shopPage")
    public R<Page<OrderCommentVo>> shopPage(@RequestBody QueryOrderComment queryOrderComment){
        Page<ShopOrderComment> page = Page.of(queryOrderComment.getCurrent(), queryOrderComment.getSize());
        Long shopId = shopBaseService.queryShopBaseIdByUserId(SecurityUtils.getUserId());
        if (ObjectUtils.isEmpty(shopId))return R.fail(MessageUtils.message("shop.not.exist"));
        LambdaQueryWrapper<ShopOrderComment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopOrderComment::getShopId,shopId);
        if (ObjectUtils.isNotEmpty(queryOrderComment.getRating())){
            queryWrapper.eq(ShopOrderComment::getRating,queryOrderComment.getRating());
        }
        queryWrapper.eq(ShopOrderComment::getParentId,"0");
        queryWrapper.eq(ShopOrderComment::getEnable,"1");
        queryWrapper.eq(ShopOrderComment::getDeleted,false);
        queryWrapper.orderByDesc(ShopOrderComment::getCreatedTime);
        Page<ShopOrderComment> commentList = commentService.page(page, queryWrapper);
        Page<OrderCommentVo> pageTree = new Page<>();
        BeanUtil.copyProperties(commentList,pageTree);
        pageTree.setRecords(new ArrayList<OrderCommentVo>());
        if (ObjectUtils.isEmpty(commentList.getRecords()))return R.ok(pageTree);
        for (ShopOrderComment record : commentList.getRecords()) {
            OrderCommentVo commentVo = new OrderCommentVo();
            BeanUtil.copyProperties(record,commentVo);
            //根据用户id查询头像
            H2AppUser appUser = userService.getById(commentVo.getUserId());
            commentVo.setUserAvatar(appUser.getAvatar());
            LambdaQueryWrapper<ShopOrderComment> queryWrapperChild = new LambdaQueryWrapper<>();
            queryWrapperChild.eq(ShopOrderComment::getParentId,record.getId());
            List<ShopOrderComment> commentChild = commentService.list(queryWrapperChild);
            commentVo.setChildOrderComent(commentChild);
            pageTree.getRecords().add(commentVo);
        }
        return R.ok(pageTree);
    }
    @Operation(summary = "删除评论")
    @DeleteMapping("/{id}")
    public R del(@PathVariable Long id){
        ShopOrderComment comment = commentService.getById(id);
        if (ObjectUtils.isEmpty(comment))return R.fail(MessageUtils.message("comment.does.not.exist"));
        comment.setDeleted(true);
       return commentService.updateById(comment)? R.ok():R.fail();
    }
}
